﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public enum SceneState
{
    Idle,
    LoadingData,
    ReleaseLoadingData,
    Entering,
    CancelEnter,
    LoadSceneObject,
    ReleaseSceneObject,
    Running
}
public abstract class LoadVo
{
    private float m_toProgress = 100;
    private float m_displayProgress = 0;
    public bool IsWorking { get { return m_IsWorking; } }
    protected bool m_IsWorking;

    /// <summary>
    /// 进度
    /// </summary>
    public float LoadPrograss
    {
        get
        {
            switch (m_State)
            {
                case SceneState.LoadingData:
                    return m_LoadDataPrograss * 0.5f;
                case SceneState.Entering:
                case SceneState.CancelEnter:
                    return 0.5f + ((m_displayProgress / m_toProgress) * 0.8f + op.progress * 0.2f) * 0.5f;
                case SceneState.LoadSceneObject:
                case SceneState.ReleaseLoadingData:
                case SceneState.ReleaseSceneObject:
                case SceneState.Running:
                    return 1;
            }
            return 0;
        }
    }

    public float Releaseprograss
    {
        get
        {
            switch (m_State)
            {
                case SceneState.CancelEnter:
                    return op.progress * 0.5f;
                case SceneState.ReleaseLoadingData:
                    return m_ReleaseDataPrograss * 0.5f + 0.5f;
                case SceneState.Idle:
                    return 1;
            }
            return 0;
        }
    }

    protected float m_LoadDataPrograss;

    protected float m_ReleaseDataPrograss;

    /// <summary>
    /// 状态
    /// </summary>
    public SceneState State { get { return m_State; } }
    protected SceneState m_State = SceneState.Idle;

    private AsyncOperation op;

    public void LoadData(object data)
    {
        m_IsWorking = true;
        m_State = SceneState.LoadingData;
        OnStartLoadData(data);   
    }

    public void EndEnter()
    {
        if (m_IsWorking)
        {
            if (m_State == SceneState.Entering)
            {
                if (op.progress >= 0.9f && op.isDone)
                {
                    m_IsWorking = false;
                    LoadingView.Instance.CloseLoadView();
                }
            }
        }
    }

    public void Update()
    {
        if (!m_IsWorking)
        {
            switch (m_State)
            {
                case SceneState.LoadingData:
                    m_IsWorking = true;
                    op = SceneManager.LoadSceneAsync(SceneName);
                    op.allowSceneActivation = false;
                    m_displayProgress = 0;        
                    m_State = SceneState.Entering;
                    break;
                case SceneState.Entering:
                    m_IsWorking = true;
                    OnStartLoadSceneObject();              
                    m_State = SceneState.LoadSceneObject;
                    break;
                case SceneState.LoadSceneObject:
                    EventListener.dispatchEvent(LoadingEvents.CLOSE_LOADING_SCENE, null);
                    m_State = SceneState.Running;
                    Debug.Log(SceneName + ":加载完成");
                    break;
                case SceneState.CancelEnter:
                    m_IsWorking = true;
                    m_ReleaseDataPrograss = 0;
                    m_State = SceneState.ReleaseLoadingData;
                    OnReleaseLoadData();
                    break;
                case SceneState.ReleaseLoadingData:
                    m_ReleaseDataPrograss = 1;
                    m_State = SceneState.Idle;
                    break;
                case SceneState.ReleaseSceneObject:
                    if (LoadingEvents.HasOpenLoad)
                    {
                        m_IsWorking = true;
                        OnReleaseLoadData();
                        m_State = SceneState.ReleaseLoadingData;
                    }
                    else
                    {
                        LoadingView.Instance.OpenLoadingScene();
                    }
                    break;
            }
        }
        else
        {
            if (m_State == SceneState.Entering)
            {
                if (m_displayProgress < m_toProgress)
                {
                    m_displayProgress += 2;
                }
                else
                {
                    if (op.progress >= 0.9f)
                    {
                        if (!op.allowSceneActivation && LoadingEvents.WaitCloseView)
                        {
                            if (!LoadingEvents.IsGradient)
                                LoadingView.Instance.CloseLoadingScene();
                            op.allowSceneActivation = true;
                        }
                        else
                            LoadingView.Instance.CloseLoadingScene();
                    }
                }
            }
            if (m_State == SceneState.CancelEnter)
            {
                if (op.isDone)
                {
                    m_IsWorking = false;
                }
            }
            OnUpdate();
        }
    }

    public void DestroyData()
    {
        switch (m_State)
        {
            case SceneState.LoadingData:
                m_IsWorking = true;
                m_ReleaseDataPrograss = 0;
                m_State = SceneState.ReleaseLoadingData;
                OnReleaseLoadData();

                break;
            case SceneState.Entering:
                m_IsWorking = true;
                op.allowSceneActivation = true;
                m_State = SceneState.CancelEnter;
                break;

            case SceneState.Running:
            case SceneState.LoadSceneObject:
                m_IsWorking = true;
                m_ReleaseDataPrograss = 0;
                m_State = SceneState.ReleaseSceneObject;
                OnReleaseSceneObject();
                break;
        }
    }

    public abstract string SceneName { get; }

    /// <summary>
    /// 加载数据
    /// </summary>
    protected abstract void OnStartLoadData(object data);

    /// <summary>
    /// 释放数据
    /// </summary>
    protected abstract void OnReleaseLoadData();


    /// <summary>
    /// 开始加载场景物体
    /// </summary>
    protected abstract void OnStartLoadSceneObject();


    protected abstract void OnReleaseSceneObject();


    /// <summary>
    /// 在Update中刷新
    /// </summary>
    protected abstract void OnUpdate();
}
